/*
    失败——逻辑本身很简单，
    不排除是stack的视线出了问题；

    2023.11.27
    换成了正确的Stack以后，就OK了
    还是要特别注意
    其实我的策略是.....以后，我会把参数列表顺序转换成我熟悉的顺序
*/
#include "stack.h"

#include <stdlib.h>

int is_right_enclose(char ch)
{
    return ( ('}' == ch) || (')' == ch) || (']' == ch) );
}

int is_left_enclose(char ch)
{
    return ( ('{' == ch) || ('(' == ch) || ('[' == ch) );
}

int is_match_right_enclose(char ch,char left)
{
    if( ('}' == ch) && ('{' == left) )
        return 1;

    if( (')' == ch) && ('(' == left) )
        return 1;    

    if( (']' == ch) && ('[' == left) )
        return 1;         

    return 0;
}

// 是有效字符串      ，返回0
// 注：空字符串是有效
// 是无效字符串或异常 ，返回-1

// 退出太早，没有释放
// 功能失败
int check_enclose(char *str)
{
    Stack pStack;
    size_t pos;
    size_t len;
    char top;
    int ret;

    if(NULL == str)
        return -1;

    if('\0' == str[0])
        return 0;

    pStack = CreateStack();

    len = strlen(str);
    
    //for(pos = 0;pos < len;len++)                 // 我的天
    for(pos = 0;pos < len;pos++)
    { 
        if(1 == is_right_enclose(str[pos]) )
        {
            // top = stack_top(pStack);            // 这个条件错了
            // if(-1 == top)
            //     return -1;

            if(1 == IsStackEmpty(pStack) )        // ↑ 这是对上述错误的修正
                 return -1;            

            top = TopStack(pStack);
            if(1 != is_match_right_enclose(str[pos],top) )
                return -1;
            else    
                PopStack(pStack);
            
        }
        else if(1 == is_left_enclose(str[pos]))
            PushStack(str[pos],pStack);
        else                                                // 非左 非右 非空，也是无效enclose字符串
            return -1;
    }

    if(1 != IsStackEmpty(pStack) )        // 此时还没空就是不对的
        return -1;    

    DisposeStack(pStack);

    return 0;
}

// test 
#include <stdio.h>
#include <stdbool.h>
void test_check_enclose(char *str,bool is_true)
{
    int ret;

    if(NULL != str)
        printf("check : %s\n",str);
    else    
        return;

    ret = check_enclose(str);
    if( (0 == ret) && (true == is_true) )
        printf("test check_enclose() SUCCESS.\n");
    else if( (-1 == ret) && (false == is_true) )
        printf("test check_enclose() SUCCESS.\n");
    else
        printf("test check_enclose() FAILURE.\n");
}

// end of file ----------------------------------------------------------------
